import { sequelize, Document, Task, Progress, Answer, User } from '../models'
import { sendNotification } from './notification'
import JOBS from '../jobs'
import EVENTS from '../events'

/**
 * Create an answer for task progress
 * @param {object} input: { progressId, documentId, userId, data }
 * @return {object} Answer
 */
export const createOrUpdate = async ({
  progressId,
  versionId,
  documentId,
  userId,
  data,
  costSeconds
}) => {
  return sequelize.transaction(async t => {
    let progress = await Progress.findById(progressId, { transaction: t })
    if (progress == null) {
      throw new Error(`${ERRORS.DBERR.ERR_RECORD_NOT_FOUND}`)
    }
    if (progress.userId != userId) {
      throw new Error(`${ERRORS.DBERR.ERR_UNAUTHORIZED_OPERATION}`)
    }
    let lastProgressState = progress.state
    versionId = versionId || progress.versionId
    let existingAnswer = await Answer.findOne({
      where: {
        userId,
        progressId,
        versionId
        //        state: 'done'
      }
    })
    // always create answer
    let user = await User.findById(userId)
    let userInfo = null
    if (user) {
      userInfo = {
        id: user.id,
        nickName: user.nickName,
        avatarUrl: user.avatarUrl
      }
    }
    let answer = await Answer.create(
      {
        data,
        userId,
        documentId: progress.documentId,
        versionId: versionId,
        progressId,
        costSeconds,
        taskId: progress.taskId,
        userInfo,
        state: 'done',
        unreadCount: 1
      },
      { transaction: t }
    )
    /* else {
      answer.data = data
      answer.costSeconds += costSeconds || 0
      await answer.save({ transaction: t })
    } */
    // TODO: upgrade progress based on task number
    progress.finishAt = new Date()
    progress.costSeconds += costSeconds || 0
    progress.unreadCount = 1
    progress.state = 'done'
    await progress.save({ transaction: t })

    EVENTS.emit('answer-after', {versionId, progressId, lastProgressState })

    return answer
  })
}

/**
 * Remove an existing answer
 * @param {int} answerId
 * @param {int} userId
 * @return {object} Answer
 */
export const remove = async (answerId, userId) => {
  let answer = await Answer.findById(answerId)
  if (answer == null) {
    return null
  }
  if (userId && answer.userId != userId) {
    throw new Error(`${ERRORS.DBERR.ERR_UNAUTHORIZED_OPERATION}`)
  }
  return await answer.destroy()
}

/**
 * List all progresses for the task
 * Order by updateAt
 * @param {string} progressId
 * @return {Answer}
 */
export const findProgressAnswer = async progressId => {
  const result = await Answer.findOne({
    where: {
      progressId
    }
  })
  return result
}
